﻿//---*Authenticity Seal
/*			                                _ .--.
					                       ( `    )
									     .-'      `--,
			                  _..----.. (             )`-.
			                .'_|` _|` _|(  .__,           )
						   /_|  _|  _|  _(        (_,  .-'
			              ;|  _|  _|  _|  '-'__,--'`--'
			              | _|  _|  _|  _| |
			          _   ||  _|  _|  _|  _|
			        _( `--.\_|  _|  _|  _|/
			      .-'       )--,|  _|  _|.`
				(__, (_      ) )_|  _| /
			      `-.__.\ _,--'\|__|__/
			                    ;____;
			                     \  /
								  OO
			                     |""|
			                     '=='
			                     
           			 Autor: Federico Angel Donnet
*/
//---*Authenticity Seal
//---*Esta clase controla y administra los diferentes sonidos que vamos a usar en nuestro proyecto:
//---*Usa "Packages"(Paquetes) que contienen listas/vectores de sonidos
//---*La idea de usar estos paquetes es para tener todo mas ordenado y que sean mas faciles de buscar (por nombre, por ejm)

using UnityEngine;
using System.Collections;
//---*Para usar Listas!
using System.Collections.Generic;
public class SoundFactoyControllerScript : MonoBehaviour
{
	//----------------//
	//---*Atributos:
	//----------------//
	//---*Instancia unica Singleton:
	private static 				SoundFactoyControllerScript		instance	=	null;
	//---*Vector de Packages:
	[HideInInspector]
	public	GameObject[]		Packages									=	null;	
	//---*Cantidad de AudioSources que va a tener el pool de AudioSources (por defecto 5):
	[HideInInspector]
	public	int					nAudioSources								=	5;
	//---*Lista de los Transforms de los Packages que se van a usar:
	//---*Las referencias las vamos a meter en una lista porque luego es mucho mas facil y rapido (en caso que sea necesario)
	//---*liberar la memoria de los members (cosa que no se puede en un vector):
	private	List<GameObject>	packages									=	null;
	//---*Lista privada que hace de pool de gameObjects con AudioSource (para poder reproducir sonidos):
	private	List<AudioSource>	sources										=	null;
	//---*Transform del gameObject que va a hacer de parent de todos los gameObjects con AudioSource:
	private	Transform			sourceParent								=	null;
	//---*Transform del gameObject que va a hacer de parent de todos los SoundPackages:
	private	Transform			packagesParent								=	null;

	//----------------//
	//---*Metodos:
	//----------------//
	//---*Instancia Singleton static:
	public static SoundFactoyControllerScript getInstance()
	{

		//---*Si la instancia no es nula, la devuelve
			//---*Pero si es nula, crea un gameObject con dicha instancia:
		if(instance	== null)
		{
			//---*Instancia un GameObject de nombre "SoundFactoryInstance" y le aniade como componente
			//---*este Script Singleton:
			instance = new GameObject("SoundFactoryInstance").AddComponent<SoundFactoyControllerScript>(); 
			Debug.Log("[SOUNDFACTORY] Se Crea el SoundFactory!!!");

		}
		return instance;
	}
	public	void Start()
	{
		//---*Si el sourceParent no existe:
		if(this.sourceParent == null)
		{
			this.sourceParent 								=	new GameObject("AudioSourceParent").transform;
			this.sourceParent.position						=	Vector3.zero;
			this.sourceParent.rotation						=	new Quaternion (0.0f,0.0f,0.0f,0.0f);
			this.sourceParent.transform.parent				=	this.gameObject.transform;
		}
		//---*Si el packagesParent no existe:
		if(this.packagesParent == null)
		{
			this.packagesParent 							=	new GameObject("SoundPackagesParent").transform;
			this.packagesParent.position					=	Vector3.zero;
			this.packagesParent.rotation					=	new Quaternion (0.0f,0.0f,0.0f,0.0f);
			this.packagesParent.transform.parent			=	this.gameObject.transform;
		}
		//---*Instanciamos la lista de AudioSources si esta no existe:
		if(this.sources == null)
		{
			this.sources	=	new List<AudioSource>();		
			//---*Creamos el pool de n GameObjects y les asignamos el componente "AudioSource":
			for(int n=0;n<this.nAudioSources;n++)
			{
				this.sources.Add( new GameObject("AudioSourceMember").AddComponent<AudioSource>());
				this.sources[n].gameObject.transform.position	=	Vector3.zero;
				this.sources[n].gameObject.transform.rotation	=	new Quaternion (0.0f,0.0f,0.0f,0.0f);
				//---*Le decimos que sean childs del Transform de AudioSources:
				this.sources[n].gameObject.transform.parent		=	this.sourceParent;
				this.sources[n].gameObject.GetComponent<AudioSource>().playOnAwake = false;
			}
		}

		//---*Instanciamos la Lista de members, si esta es null:
		if(this.packages == null)
		{
			this.packages = new List<GameObject>();		
			//---*Recorremos el vector de Packages y los instanciamos,
			//---*Almacenamos las referencias en la lista "packages":
			if(this.Packages != null)
			{
				for (int n=0;n<this.Packages.Length;n++)
				{
					this.packages.Add(Instantiate(this.Packages[n]) as GameObject);
					this.packages[n].transform.position				=	Vector3.zero;
					this.packages[n].transform.rotation				=	new Quaternion (0.0f,0.0f,0.0f,0.0f);
					//---*Le decimos que sean childs del Transform del PackagesParent:
					this.packages[n].transform.parent				=	this.packagesParent.transform;				
				}
			}
		}
	}
	public	void Init()
	{
		instance = getInstance();
		Debug.Log("[SOUNDFACTORY] IM READY TO THE SHOW!");
	}
	//---*Reproduce un sonido 2D al azar del Package especificado (por el name):
	//---*NOTA: Al referirce "2D" no es por el tipo de sonido... sino que al llamar a 
	//---*esta funcion el sonido se va a reproducir en uno de los AudioSource de este Script:
	public	void PlayRandomSound2D(string name)
	{
		if(this.packages != null)
		{
			if(this.packages.Count > 0)
			{
				//---*Recorremos los members y buscamos el del mismo name:
				for (int n=0;n<this.packages.Count;n++)
				{
					//---*Si encuentra el Package indicado:
					if(this.packages[n].GetComponent<SoundPackage>().PackageName == name)
					{
						int nClips = this.packages[n].GetComponent<SoundPackage>().nClips;
						PlaySound2D(this.packages[n].GetComponent<SoundPackage>().clips[Random.Range(0,nClips)]);
						//---*Le decimos que finalice la busqueda:			
						break;
					}

				}
			}
		}
		else 
		{
			Debug.Log ("[SOUNDFACTORY] NO HAY PAQUETES DE SONIDO!!!!");
		}

	}
	//---*Recibe el AudioClip y lo reproduce en el primer
	//---*AudioSource que encuentre disponible (o sea, que NO este reproduciendo sonido):
	void PlaySound2D(AudioClip clip)
	{
		//---*Recorre el pool de GameObjects con el componente "AudioSource":
		for (int n=0;n<this.sources.Count;n++)
		{
			//---*Si el AudioSource de turno no esta reproduciendo sonido:
			if(!this.sources[n].isPlaying)
			{
				this.sources[n].clip = clip;
				this.sources[n].Play();
				//---*Le decimos que finalice la busqueda:
				break;
			}
		}
	}

}
